package top.cardone.web.support;

import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import top.cardone.context.ApplicationContextHolder;
import top.cardone.context.util.TableUtils;
import top.cardone.core.CodeException;
import top.cardone.mapper.BeanMapper;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

/**
 * Created by yht on 16-3-23.
 */
@Log4j2
public class WebSupport {
	/**
	 * 获取对象
	 *
	 * @param cls
	 * @param request
	 * @param <T>
	 * @return
	 */
	public <T> T getObject(Class<T> cls, HttpServletRequest request) {
		if (StringUtils.startsWith(request.getContentType(), org.springframework.http.MediaType.APPLICATION_JSON_VALUE)) {
			T t = this.getObjectByJson(cls, request);

			return t;
		}

		T t = this.getObjectByParameter(cls, request);

		return t;
	}

	public Map<String, Object> getObject(HttpServletRequest request, String inputTableJsonPath, boolean cache) {
		return this.getObject(Map.class, request, inputTableJsonPath, cache);
	}

	public Map<String, Object> getObject(HttpServletRequest request, String[] inputJsons, boolean cache) {
		return this.getObject(Map.class, request, inputJsons, cache);
	}

	public Map<String, Object> getTable(HttpServletRequest request, String[] inputJsons, boolean cache) {
		return ApplicationContextHolder.getBean(BeanMapper.class).getTable(this.getObject(Map.class, request), inputJsons, cache);
	}

	public <T> T getObject(Class<T> cls, HttpServletRequest request, String[] inputJsons, boolean cache) {
		if (ArrayUtils.isEmpty(inputJsons)) {
			return this.getObject(cls, request);
		}

		T t = (T) ApplicationContextHolder.getBean(BeanMapper.class).getObject(cls, this.getObject(Map.class, request), inputJsons, cache);

		return t;
	}

	public <T> T getObject(Class<T> cls, HttpServletRequest request, String inputTableJsonPath, boolean cache) {
		if (StringUtils.isBlank(inputTableJsonPath)) {
			return this.getObject(cls, request);
		}

		Map<String, Object> newMap = top.cardone.context.util.MapUtils.newHashMap(this.getObject(Map.class, request), TableUtils.newTable(inputTableJsonPath, cache));

		T t = ApplicationContextHolder.getBean(BeanMapper.class).getObject(cls, newMap);

		return t;
	}

	public Map<String, Object> getObject(HttpServletRequest request, Map<String, Object> mapperMap) {
		return this.getObject(Map.class, request, mapperMap);
	}

	public <T> T getObject(Class<T> cls, HttpServletRequest request, Map<String, Object> mapperMap) {
		if ((mapperMap == null) || mapperMap.isEmpty()) {
			return this.getObject(cls, request);
		}

		T t = (T) ApplicationContextHolder.getBean(BeanMapper.class).getObject(cls, this.getObject(Map.class, request), mapperMap);

		return t;
	}

	/**
	 * 获取对象
	 *
	 * @param cls
	 * @param request
	 * @param <T>
	 * @return
	 */
	public <T> T getObjectByJson(Class<T> cls, HttpServletRequest request) {
		try (java.io.InputStream is = request.getInputStream()) {
			String jsonString = StringUtils.trim(IOUtils.toString(is, request.getCharacterEncoding()));

			T t = ApplicationContextHolder.getBean(BeanMapper.class).getObject(cls, jsonString, org.springframework.web.util.WebUtils.getParametersStartingWith(request, null));

			return t;
		} catch (IOException e) {
			throw new CodeException("000012", new String[]{e.getMessage()}, e);
		}
	}

	/**
	 * 获取对象
	 *
	 * @param cls
	 * @param request
	 * @param <T>
	 * @return
	 */
	public <T> T getObjectByParameter(Class<T> cls, HttpServletRequest request) {
		T t = ApplicationContextHolder.getBean(BeanMapper.class).getObject(cls, org.springframework.web.util.WebUtils.getParametersStartingWith(request, null));

		return t;
	}
}